mod riscv64;

mod cpu;
pub mod rtl;

use crate::memory::Memory;

use cpu::Cpu;
pub use riscv64::{gpr, Riscv64};
use rtl::Rtl;

/// 字，里面关联了特定的 无符号整型和有符号整型
pub trait Word: Sized {
    type UInt: num_traits::int::PrimInt + num_traits::AsPrimitive<usize>;
    type Int: num_traits::int::PrimInt + num_traits::AsPrimitive<isize>;
    const BIT_WIDTH: usize;
}

impl Word for u64 {
    type Int = i64;
    type UInt = u64;
    const BIT_WIDTH: usize = 64;
}

impl Word for u32 {
    type Int = i32;
    type UInt = u32;
    const BIT_WIDTH: usize = 32;
}

// 里面要写这一串太长了。。。
pub type WordOf<T> = <<T as Isa>::Word as Word>::UInt;
pub type IWordOf<T> = <<T as Isa>::Word as Word>::Int;
pub type CpuOf<T> = <T as Isa>::Cpu;
pub type MemoryOf<T> = <T as Isa>::Memory;
pub(crate) type RtlOf<T> = Rtl<IWordOf<T>, WordOf<T>>;

/// Isa
pub trait Isa {
    /// 字类型
    type Word: Word;
    /// 内存
    type Memory: Memory; // 这个真的有必要放这里吗？
    /// cpu
    type Cpu: Cpu<Self::Word>;
    /// 通用寄存器数量
    const GPR_NUMBER: usize;
    /// 启动时执行的第一条指令地址
    const PROG_START: WordOf<Self>;

    /// 执行 n 条指令
    fn exec(cpu: &mut Self::Cpu, mem: &mut Self::Memory, n: usize);
}
